using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace ZombieHigh2.Menus
{
	public class TextSwirl
	{
		Vector3 startPosition;
		Vector3 endPosition;
		Vector3 currentPosition;
		float totalTravelTime;		//How long it should take to reach endPosition from startPosition
		float currentTravelTime;	//Current time along path
		Model model;
        Texture2D texture;
        float rotationAngle;
        float currentRotationAngle;
        float targetRotationAngle;
		int state;
		
		const int STATE_AT_START = 0;
		const int STATE_MOVING_TO_END = 1;
		const int STATE_AT_END = 2;
		const int STATE_MOVING_TO_START = 3;
		
		#region PROPERTIES
		public Boolean IsAtStart
		{
			get { return state == STATE_AT_START; }
		}
		
		public Boolean IsAtEnd
		{
			get { return state == STATE_AT_END; }
		}
		
		public Boolean IsMovingToEnd
		{
			get {return state == STATE_MOVING_TO_END; }
		}
		
		public Boolean IsMovingToStart
		{
			get { return state == STATE_MOVING_TO_START; }
		}
		#endregion
		
		public TextSwirl(Model model, Texture2D texture, Vector3 start, Vector3 end, float travelTime)
		{
			this.model = model;
			this.startPosition = start;
			this.endPosition = end;
			this.state = STATE_AT_START;
			this.totalTravelTime = travelTime;
            this.texture = texture;
			currentTravelTime = 0f;
			currentPosition = start;
            rotationAngle = 90f;
            currentRotationAngle = rotationAngle;
            targetRotationAngle = 0f;
		}
		
		public void Update(float elapsedTime)
		{
			Vector3 ray;
			float timeInterval;
			
			if (state == STATE_MOVING_TO_END)
			{
                currentTravelTime += elapsedTime;
				ray = endPosition - startPosition;
                timeInterval = currentTravelTime / totalTravelTime;
				currentPosition = startPosition + ray * timeInterval;
                currentRotationAngle = rotationAngle + (targetRotationAngle - rotationAngle) * currentTravelTime;
				
				if (timeInterval > 1.0f)
				{
					currentPosition = endPosition;
                    currentTravelTime = 0f;
					state = STATE_AT_END;
                    currentRotationAngle = targetRotationAngle;
				}
			}
			else if (state == STATE_MOVING_TO_START)
			{
                currentTravelTime += elapsedTime;
				ray = startPosition - endPosition;
                timeInterval = currentTravelTime / totalTravelTime;
                currentPosition = endPosition + ray * timeInterval;
                currentRotationAngle = targetRotationAngle + (rotationAngle - targetRotationAngle) * currentTravelTime;

                if (timeInterval > 1.0f)
				{
					currentPosition = startPosition;
                    currentTravelTime = 0f;
					state = STATE_AT_START;
                    currentRotationAngle = rotationAngle;
				}
			}
		}
		
		public void MoveToEnd()
		{
			if (state == STATE_AT_START)
			{
				state = STATE_MOVING_TO_END;
				currentTravelTime = 0f;
			}
		}
		
		public void MoveToStart()
		{
			if (state == STATE_AT_END)
			{
				state = STATE_MOVING_TO_START;
				currentTravelTime = 0f;
			}
		}

        public void Draw(Matrix viewMatrix, Matrix projectionMatrix)
        {
            DrawModel(viewMatrix, projectionMatrix);
        }

        void DrawModel(Matrix viewMatrix, Matrix projectionMatrix)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.View = viewMatrix;
                    effect.Projection = projectionMatrix;
                    effect.Texture = texture;
                    effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationZ(MathHelper.ToRadians(currentRotationAngle))* Matrix.CreateTranslation(currentPosition);
                }
                mesh.Draw();
            }
        }
	}
}